import React, { useState, useMemo, useEffect } from 'react';
import { ColView, filter_list, useHigh, GridTable, filter_row, useCmd, WaitUmd, MainView, no_del, trim_data, KFile, HandView, BtTxt,
    Title, cline, uPlc, BtSwitch, alert_st, show_mt, obj_int, obj_str, PanelFind, Btn, is_empty, loc } from 'sui';
import { st_list, add_pick, load_supply, fix_col, get_ck, load_col } from './cmd';
import { face_list, load_stuff } from 'test/base/cmd';
import { useAccess } from 'cache';
import { DlgVal } from './ctl';
import { CSview } from './census/cs/view';
import { FLview } from './census/fl';
import { GTview } from './census/gt/gt';
import { get_alert } from 'pair/cmd';
import { show_val } from 'buy/task/cmd';

const BaseView = ({ mod, title, acc }) => {
    const [alert, setAlert] = useState();
    const [show_zero, showZero] = useState(false);
    const [open_val, openVal] = useState(false);
    const [supply, setSupply] = useState();
    const [map_supply, mapSupply] = useState();
    const [stuff, setStuff] = useState();
    const [map_stuff, mapStuff] = useState();
    const [col, setCol] = useState();
    const [high] = useHigh(190, 100);
    const [no_acc] = useAccess();
    const umd = useCmd(`${mod}/list`);

    useEffect(() => {
        get_alert(setAlert);
        load_col(mod, setCol);
        load_supply(mod, setSupply, mapSupply);
        if (mod === "cage") {
            load_stuff(setStuff, mapStuff);
        }
    }, [mod]);

    const getRow = useMemo(() => {
        const lst = filter_list(["sn"], col);

        let ret = filter_row(umd.value, lst, umd.filter);

        if (show_zero || is_empty(ret)) {
            return ret;
        }

        ret = ret.filter(d => obj_int(d, "dnum") > 0);
        if (is_empty(ret)) {
            return ret;
        }

        ret.forEach((d, i) => d["posid"] = i);

        return ret;
    }, [umd.value, umd.filter, col, show_zero]);

    const hreturn = () => {
        load_col(mod, setCol);
        umd.hreturn();
    };

    const calc_v = (v) => {
        const dnum = obj_int(v, "dnum");
        const bnum = obj_int(v, "bnum");
        v["num"] = dnum + bnum;

        return v;
    };

    const act = {
        "add": (v, h) => umd.update(`${mod}/add`, {"v": calc_v(v)}, h),
        "edit": (v, h) => umd.update(`${mod}/md`, {"v": [calc_v(v)]}, h),
        "pick": (v) => add_pick(mod, v, umd.cur, umd),
    };

    const pact = {
        "pick": v => openVal(true),
        "alert": v => {
            if (no_del(loc("l_890"))) {
                return;
            }

            umd.startWait();

            uPlc(null, "clear",
                {
                    line: cline(),
                    sn: "alertmsg",
                    v: [`miss#${obj_str(v, "sn")}`],
                },
                r => {
                    get_alert(setAlert);
                    umd.reload(umd.endWait);
                }, e => umd.setErr());
        }
    };

    if (umd.isFin("col")) {
        const list = [
            {sn: mod, name: title, fix: fix_col()},
        ];

        return <ColView hreturn={hreturn} title={title} subtitle={loc("l_221")} list={list} cur={mod}/>;
    } else if (umd.isFin("census")) {
        if (mod === "cera" || mod === "stell") {
            return <GTview data={umd.value} hreturn={() => umd.hreturn()} title={title} mod={mod}/>;
        }

        if (mod === "forge" || mod === "lathe") {
            return <FLview data={umd.value} hreturn={() => umd.hreturn()} title={title} mod={mod}/>;
        }

        return <CSview data={umd.value} hreturn={() => umd.hreturn()} title={title} mod={mod} col={col} map_supply={map_supply} map_stuff={map_stuff}/>;
    }

    const hDel = (d) => {
        if (no_del()) {
            return;
        }

        umd.update(`${mod}/rm`, {"k": obj_str(d, "sn")});
    };

    const hCol = () => {
        if (is_empty(col)) {
            return null;
        }

        const ret = [];

        col.forEach(d => {
            if (d.sn === "tmget" || d.sn === "tmin") {
                d.ctp = "datetime";
            } else if (d.sn === "face") {
                d.ctp = "list";
                d.ctl = face_list();
            } else if (d.sn === "state") {
                d.ctp = "list";
                d.ctl = st_list();
            } else if (d.sn === "supply") {
                d.ctp = "list";
                d.ctl = supply;
            } else if (d.sn === "stuff") {
                d.ctp = "list";
                d.ctl = stuff;
            }

            ret.push(d);
        });

        return ret;
    };

    if (umd.isFin("edit") || umd.isFin("add")) {
        return <HandView umd={umd} title={title} act={act} col={hCol()} ck={get_ck(umd.cur, umd.value, col)}/>;
    }

    const hImport = (val) => {
        if (is_empty(col)) {
            alert(loc("l_686"));
            return;
        }

        if (is_empty(val)) {
            alert(loc("l_276"));
            return;
        }

        trim_data(val, ["sn"]);

        umd.update(`${mod}/madd`, {v: val});
    };

    const getCol = () => {
        if (is_empty(col)) {
            return null;
        }

        const tmp = [
            {name: loc("l_193"), key: 'index', width: 70, frozen: true},
            {name: loc("l_238"), key: 'e_opt', width: 243, frozen: true, formatter: props => {
                const d = props.row;
                return (
                    <div className="inline-flex">
                        <BtTxt hcmd={() => umd.pact(pact, d, "pick")} disabled={no_acc(acc + "b")}>{loc("l_741")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(null, d, "edit")} disabled={no_acc(acc + "a")}>{loc("l_235")}</BtTxt>
                        <BtTxt hcmd={() => hDel(d)} disabled={no_acc(acc + "a")}>{loc("l_237")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(pact, d, "alert")} disabled={no_acc(acc + "a")}>{loc("l_890")}</BtTxt>
                    </div>
                );
            }},
            {name: loc("l_131"), key: 'st', width: 70, frozen: true, formatter: (props) => {
                const d = props.row;
                return alert_st(d, alert);
            }},
        ];

        col.forEach(d => {
            if (d.sn === "supply") {
                tmp.push({name: d.name, key: d.sn, width: 150, formatter: props => show_val(props, "supply", map_supply)});
            } else if (d.sn === "stuff") {
                tmp.push({name: d.name, key: d.sn, width: 150, formatter: props => show_val(props, "stuff", map_stuff)});
            } else {
                show_mt(tmp, d, 150);
            }
        });

        return tmp;
    };

    const getList = () => {
        if (is_empty(col)) {
            return null;
        }

        return col.map(d => d.sn);
    };

    const rowTempl = () => {
        const tmp = getList();
        if (is_empty(tmp)) {
            return null;
        }

        const v = {};
        tmp.forEach(k => v[k] = "1");

        return [v];
    };

    const Right = () => <BtSwitch hcmd={showZero} checked={show_zero}>{loc("l_788")}</BtSwitch>;

    const Left = () => <Title mod={title} sub={loc("l_323")}/>

    return (
        <MainView>
            <PanelFind left={<Left/>} right={<Right/>} hcmd={v => umd.setFilter(v)}>
                <div className="flex items-center mb-1 justify-between">
                    <Btn hcmd={() => umd.pact(null, null, "census")} disabled={no_acc(acc + "c")} color="teal">{loc("l_793")}</Btn>
                    <div className="flex items-center mr-4">
                        <Btn className="mr-4" hcmd={() => umd.pact(null, null, "col")} disabled={no_acc(acc + "a")}>{loc("l_221")}</Btn>
                        <KFile umd={umd} title={title} col={getList()} row={rowTempl()} hcmd={hImport} no_acc_in={no_acc(acc + "a")}/>
                        <Btn color="green" hcmd={() => umd.pact(null, null, "add")} className="ml-3" disabled={no_acc(acc + "a")}>{loc("l_239")}</Btn>
                    </div>
                </div>
            </PanelFind>
            <GridTable col={getCol()} row={getRow} high={high} gref={umd.gref}/>
            <DlgVal open={open_val} hcmd={v => umd.act(act, v)} setOpen={openVal} data={umd.cur} mod={mod}/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {BaseView};
